<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        body, div, h2
        {
            margin: 0;
            padding: 0;
        }
        body
        {
            background: url(image/bg.jpg);
            font: 12px/1.5 \5fae\8f6f\96c5\9ed1;
            color: #333;
        }
        
        #drag
        {
            position: absolute;
            top: 100px;
            left: 100px;

            width: 300px;
            height: 160px;
            background: #e9e9e9;
            border: 1px solid #444;
            border-radius: 5px;
            box-shadow: 0 1px 3px 2px #0ff;
        }
        #drag .title
        {
            position: relative;
            height: 27px;
            margin: 5px;
        }
        #drag .title h2
        {
            font-size: 14px;
            height: 27px;
            line-height: 27px;
            border-bottom: 1px solid #0ff;
        }
        #drag .title div
        {
            position: absolute;
            height: 19px;
            
            top: 2px;
            right: 0;
        }
        #drag .title a, a.open
        {
            float: left;
            width: 21px;
            height: 19px;
            display: block;
            margin-left: 5px;
            background: url(image/tool.png) no-repeat;
        }
        a.open
        {
            position: absolute;
            top: 10px;
            left: 50%;
            margin-left: -10px;
            background-position: 0 0;
        }
        a.open:hover
        {
            background-position: 0 -29px;
        }

        #drag .title a.min
        {
            background-position: -29px 0;
        }
        #drag .title a.min:hover
        {
            background-position: -29px -29px;
        }
        #drag .title a.max
        {
            background-position: -60px 0;
        }
        #drag .title a.max:hover
        {
            background-position: -60px -29px;
        }
        #drag .title a.revert
        {
            background-position: -149px 0;
            display: none;
        }
        #drag .title a.revert:hover
        {
            background-position: -149px -29px;
        }
        #drag .title a.close
        {
            background-position: -89px 0;
        }
        #drag .title a.close:hover
        {
            background-position: -89px -29px;
        }

        #drag .content
        {
            overflow: auto;
            margin: 0 5px;
        }
        #drag .resizeBR {
            position: absolute;
            width: 14px;
            height: 14px;
            right: 0;
            bottom: 0;

            overflow: hidden;
            cursor: nw-resize;
            background: url(image/resize.png)
        }
        #drag .resizeL, #drag .resizeT, #drag .resizeR, #drag .resizeB, #drag .resizeLT, #drag .resizeTR, #drag .resizeLB
        {
            position: absolute;
            background: #000;
            overflow: hidden;
            opacity: 0;
        }
        #drag .resizeL, #drag .resizeR
        {
            top: 0;
            width: 5px;
            height: 100%;
            cursor: w-resize;
        }
        #drag .resizeR
        {
            right: 0;
        }
        #drag .resizeT, #drag .resizeB
        {
            width: 100%;
            height: 5px;
            cursor: n-resize;
        }
        #drag .resizeT
        {
            top: 0;
        }
        #drag .resizeB
        {
            bottom: 0;
        }
        #drag .resizeLT, #drag .resizeTR, #drag .resizeLB
        {
            width: 8px;
            height: 8px;
            background: #0ff;
        }
        #drag .resizeLT
        {
            top: 0;
            left: 0;
            cursor: nw-resize;
        }
        #drag .resizeTR
        {
            top: 0;
            right: 0;
            cursor: ne-resize;
        }
        #drag .resizeLB
        {
            left: 0;
            bottom: 0;
            cursor: ne-resize;
        }
    </style>
    <script type="text/javascript">
        /*
         * 获取id， class， tagname
         */
        var get = {
            byId: function (id)
            {
                return typeof id === "string" ? document.getElementById(id) : null;
            },
            byClass: function (sClass, oParent)
            {
                // 带有类的标签，一般是数组类型，故需要一个数组来存储这些类
                var aClass = [];
                // 类名的匹配规则
                var reClass = new RegExp("(^|\s)" + sClass + "(\s|$)");
                // this指对象get本身
                var aElem = this.byTagName("*", oParent);
                for (var i=0; i<aElem.length; i++)
                {
                    reClass.test(aElem[i].className) && aClass.push(aElem[i]);
                }
                return aClass;
            },
            byTagName: function (elem, obj)
            {
                return (obj || document).getElementsByTagName(elem);
            }
        };

        var dragMinWidth = 250;
        var dragMinHeight = 124;
        /*
         * 拖曳函数
         */
        function drag (oDrag, handle)
        {
            var disX = 0, dixY = 0;
            var oMin = get.byClass("min", oDrag)[0];
            var oMax = get.byClass("max", oDrag)[0];
            var oRevert = get.byClass("revert", oDrag)[0];
            var oClose = get.byClass("close", oDrag)[0];
            handle = handle || oDrag;
            handle.style.cursor = "move";

            handle.onmousedown = function (event)
            {
                var event = event ||　window.event;
                disX = event.clientX - oDrag.offsetLeft;
                disY = event.clientY - oDrag.offsetTop;

                document.onmousemove = function (event)
                {
                    var event = event ||　window.event;
                    var iL = event.clientX - disX;
                    var iT = event.clientY - disY;
                    var maxL = document.documentElement.clientWidth - oDrag.offsetWidth;
                    var maxT = document.documentElement.clientHeight - oDrag.offsetHeight;

                    iL <= 0 && (iL = 0);
                    iT <= 0 && (iT = 0);
                    iL >= maxL && (iL = maxL);
                    iT >= maxT && (iT = maxT);

                    oDrag.style.left = iL + "px";
                    oDrag.style.top = iT + "px";
                    return false;
                };

                document.onmouseup = function (event)
                {
                    document.onmouseup = null;
                    document.onmousemove = null;
                    this.releaseCapture && this.releaseCapture();
                };
                this.setCapture && this.setCapture();
                return false;
            };

            // 最大化按钮
            oMax.onclick = function()
            {
                oDrag.style.top = oDrag.style.left = 0;
                oDrag.style.width = document.documentElement.clientWidth - 2 + "px";
                oDrag.style.height = document.documentElement.clientHeight - 2 + "px";
                // 点击之后，最大按钮消失，还原按钮出现
                this.style.display = "none";
                oRevert.style.display = "block";
            }

            // 还原按钮
            oRevert.onclick = function()
            {
                oDrag.style.width = dragMinWidth + "px";
                oDrag.style.height = dragMinHeight + "px";

                oDrag.style.left = (document.documentElement.clientWidth - oDrag.offsetWidth) / 2 + "px";
                oDrag.style.top = (document.documentElement.clientHeight - oDrag.offsetHeight) / 2 + "px";

                this.style.display = "none";
                oMax.style.display = "block";
            };

            // 最小化按钮和关闭按钮
            oMin.onclick = oClose.onclick = function()
            {
                oDrag.style.display = "none";
                // 创建一个恢复窗口的图标
                var oA = document.createElement("a");
                oA.className = "open";
                oA.href = "javascript:;";
                oA.title = "还原";

                document.body.appendChild(oA);

                oA.onclick = function()
                {
                    oDrag.style.display = "block";
                    document.body.removeChild(this);
                    this.onclick = null;
                };
            };

            // 阻止冒泡
            // 如果不阻止，在使用最小化等按钮的功能同时，还可以移动窗口
            oMin.onmousedown = oMax.onmousedown = oClose.onmousedown = function(event)
            {
                this.onfocus = function() {this.blur()}; //??????????????
                (event ||　window.event).cancelBubble = true;
            };
        }
        
        /*
         * 窗口大小改变
         */
        function resize(oParent, handle, isLeft, isTop, lockX, lockY)
        {
            handle.onmousedown = function(event)
            {
                var event = event ||　window.event;
                // 初始oDrag左侧或者上边偏移距离+鼠标相对触点所在小盒子的相对距离
                var disX = event.clientX - handle.offsetLeft;
                var disY = event.clientY - handle.offsetTop;
                // 获取oDrag的初始宽度、高度、左偏移量以及上偏移量
                var iParentTop = oParent.offsetTop;
                var iParentLeft = oParent.offsetLeft;
                var iParentWidth = oParent.offsetWidth;
                var iParentHeight = oParent.offsetHeight;

                document.onmousemove = function(event)
                {
                    var event = event || window.event;
                    // 计算移动前的初始值；
                    // 当向左或者向上时，iL和iT或小于0
                    var iL = event.clientX - disX;
                    var iT = event.clientY - disY;

                    // 设置
                    var maxW = document.documentElement.clientWidth - iParentLeft - 2;
                    var maxH = document.documentElement.clientHeight - oParent.offsetTop - 2; 

                    // 第一条件： 也一并获取到oDrag的实际参数
                    var iW = isLeft ? iParentWidth - iL : handle.offsetWidth + iL;
                    var iH = isTop ? iParentHeight - iT : handle.offsetHeight + iT;
                    // 第二条件：控制移动方向
                    isLeft && (oParent.style.left = iParentLeft + iL + "px");

                    isTop && (oParent.style.top = iParentTop + iT + "px");

                    console.log(iParentLeft);


                    // 第三条件： 设置最小和最大范围
                    // 这里有个问题：最大的范围并不仅仅是浏览器可视窗口的大小
                    // 还有两个界限需要限定：左侧偏移最大距离和右侧偏移最大距离
                    // oDrag.offsetLeft <= iParentLeft & oDrag.offsetLeft >=0
                    // document.documentElement.clientHeight - oDrag.offsetLeft - oDrag.offsetWidth <= iParentLeft & document.documentElement.clientHeight - oDrag.offsetLeft - oDrag.offsetWidth >= 0
                    iW <= dragMinWidth && (iW = dragMinWidth); //设置最小值

                    iW >= maxW && (iW = maxW);  //设置最大值为浏览器
                    // 输出最终值
                    lockX || (oParent.style.width = iW + "px");

                    iH <= dragMinHeight && (iH = dragMinHeight);
                    iH >= maxH && (iH = maxH);
                    lockY || (oParent.style.height = iH + "px");

                    if((isLeft && iW == dragMinWidth) || (isTop && iT == dragMinHeight))
                    {
                        document.onmousemove = null;
                    }
                    return false;            
                };

                document.onmouseup = function(event)
                {
                    document.onmousemove = null;
                    document.onmouseup = null;
                };
                return false;
            };
        }

        window.onload = window.onresize = function ()
        {            
            var oDrag = get.byId("drag");
            var oTitle = get.byClass("title", oDrag)[0];
            
            var oL = get.byClass("resizeL", oDrag)[0];
            var oT = get.byClass("resizeT", oDrag)[0];
            var oR = get.byClass("resizeR", oDrag)[0];
            var oB = get.byClass("resizeB", oDrag)[0];

            var oLT = get.byClass("resizeLT", oDrag)[0];
            var oTR = get.byClass("resizeTR", oDrag)[0];
            var oBR = get.byClass("resizeBR", oDrag)[0];
            var oLB = get.byClass("resizeLB", oDrag)[0];

            // 调用拖曳
            drag(oDrag, oTitle);

            // 四边
            resize(oDrag, oL, true, false, false, true);
            resize(oDrag, oT, false, true, true, false);
            resize(oDrag, oR, false, false, false, true);
            resize(oDrag, oB, false, false, true, false);

            // 四角
            resize(oDrag, oLT, true, true, false, false);
            resize(oDrag, oTR, false, true, false, false);
            resize(oDrag, oBR, false, false, false, false);
            resize(oDrag, oLB, false, false, true, false);
            oDrag.style.left = (document.documentElement.clientWidth - oDrag.offsetWidth) / 2 + "px";
            oDrag.style.top = (document.documentElement.clientHeight - oDrag.offsetHeight) / 2 + "px";
        }
    </script>
</head>
<body>
<div id="drag">
    <div class="title">
        <h2>这是一个可以拖动的窗口</h2>
        <div>
            <a href="javascript:;" class="min" title="最小化"></a>
            <a href="javascript:;" class="max" title="最大化"></a>
            <a href="javascript:;" class="revert" title="还原"></a>
            <a href="javascript:;" class="close" title="关闭"></a>
        </div>
    </div>
    <div class="resizeL"></div>
    <div class="resizeT"></div>
    <div class="resizeR"></div>
    <div class="resizeB"></div>
    <div class="resizeLT"></div>
    <div class="resizeTR"></div>
    <div class="resizeBR"></div>
    <div class="resizeLB"></div>
    <div class="content">
        ① 窗口可以拖动；<br />
        ② 窗口可以通过八个方向改变大小；<br />
        ③ 窗口可以最小化、最大化、还原、关闭；<br />
        ④ 限制窗口最小宽度/高度。
    </div>
</div>
</body>
</html>